#pragma once
#include "./_Private/_LogPrivateInc.h"


class  LogPos{
public:
    LogPos():is_empty_(true),line_(0){memset(&cur_,0,sizeof(time_t));}
    LogPos(const LogPos& oth):is_empty_(oth.is_empty_),line_(oth.line_){file_=oth.file_;func_=oth.func_;memcpy(&cur_,&oth.cur_,sizeof(time_t));}
    LogPos(LogPos&& ref):is_empty_(ref.is_empty_),line_(ref.line_){func_=std::move(ref.func_);file_=std::move(ref.file_);;memcpy(&cur_,&ref.cur_,sizeof(time_t));}
    LogPos&operator=(LogPos&& ref){is_empty_=ref.is_empty_;line_=ref.line_;func_=std::move(ref.func_);file_=std::move(ref.file_);;memcpy(&cur_,&ref.cur_,sizeof(time_t));return *this;}
    LogPos&operator=(const LogPos& ref){is_empty_=ref.is_empty_;line_=ref.line_;func_=ref.func_;file_=ref.file_;memcpy(&cur_,&ref.cur_,sizeof(time_t));return *this;}

public:
	void clear() { file_ = std::string(); func_ = std::string(); line_ = 0; is_empty_ = true; cur_ = 0; }
    inline void setFile(const str_t& file){file_=file;is_empty_=false;}
    inline void setLine(const int& line){line_=line;is_empty_=false;}
    inline void setFunc(const str_t& fun){func_=fun;is_empty_=false;}
    inline void setTime(time_t time){cur_=time;is_empty_=false;}
    str_t       getFile()const{return file_;}
    int         getLine()const{return line_;}
    str_t       getFun()const{return func_;}
    time_t      getTime()const{return cur_;}
    bool        isEmpty()const{return is_empty_;}

private:
    bool        is_empty_;
    std::string file_;
    std::string func_;
    int         line_;
    time_t      cur_;

};
typedef std::string LogData;
/*
struct LogData{
    LogData(){}
	LogData(const LogData& oth) :level_(oth.level_) { data_<< oth.data_.str(); }
    LogData(LogData&& ref):level_(ref.level_){data_=std::move(ref.data_);}
	LogData& operator =(LogData&& ref) { level_ = ref.level_; data_ = std::move(ref.data_); return *this; }
    LogData& operator =(const LogData& ref){level_=ref.level_;data_<<ref.data_.str();return *this;}

    bool isEmpty(){return (data_.tellp()<=0);}
	void clear() { level_ = 0; data_.str(""); }
    int        level_;
	ss_t       data_;
};*/
typedef std::tuple<LogPos, LogData, LOG_LEVEL> LogItem;
#define GET_LEVEL(t) (std::get<2>(t))
#define GET_LOG(t)   (std::get<1>(t))
#define GET_POS(t)   (std::get<0>(t))
class PrintBase{



public:
    PrintBase();
    virtual ~PrintBase()
    {
        while(thread_cnt_)
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }


    void pushLog(const LogItem& pair)
    {
        un_lock_t lock(mtx_);
        que_log_.push_back(pair);
        cv_.notify_one();
    }

	void pushLog(LogItem&& pair) 
    {
		un_lock_t lock(mtx_);
		que_log_.push_back(pair);
		cv_.notify_one();
	}
 
protected:
    virtual void _print()=0;
	void         _getLogItem(LogItem& itm);
    void         _getLogQuery(std::deque<LogItem>& que);
    str_t        _setLogFormat(LogItem &data);

protected:
	AtmBool                         exit_;
    AtmInt                          thread_cnt_;
    mtx_t                           mtx_;
    Cv                              cv_;
    std::deque<LogItem>             que_log_;
    

};
